package com.cpdmali.courrier.init;

import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.Servlet;
import javax.servlet.ServletRegistration.Dynamic;
import javax.sql.DataSource;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import com.cpdmali.courrier.serveur.servlet.CpdMaliCourrierServlet;

@Configuration
@ComponentScan("com.cpdmali")
@EnableWebMvc
@EnableTransactionManagement
@PropertySource("classpath:properties/application.properties")
public class WebAppConfig {

	private static final String PROPERTY_NAME_DATABASE_DRIVER = "database.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "database.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "database.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "database.username";
	
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
    
    private static final String PROPERTY_NAME_HIBERNATE_CACHE_USE_SECOND_LEVEL = "hibernate.cache.use_second_level_cache";
    private static final String PROPERTY_NAME_HIBERNATE_CACHE_USER_QUERY = "hibernate.cache.use_query_cache";
    private static final String PROPERTY_NAME_HIBERNATE_CACHE_REGION_FACTORY_CLASS = "hibernate.cache.region.factory_class";
    private static final String PROPERTY_NAME_HIBERNTTE_PROVIDER_CACHE = "hibernate.cache.provider_class";
    
    
    @Resource
	private Environment env;
	
	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		
		dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
		dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
		dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
		dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
				
		return dataSource;
	}
	
	@Bean
	public LocalSessionFactoryBean sessionFactory() {
		LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
		sessionFactoryBean.setDataSource(dataSource());
		sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
		
		sessionFactoryBean.setHibernateProperties(hibProperties());
		return sessionFactoryBean;
	}
	
	private Properties hibProperties() {
		Properties properties = new Properties();
		properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
		properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
//		properties.put(PROPERTY_NAME_HIBERNATE_CACHE_USE_SECOND_LEVEL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CACHE_USE_SECOND_LEVEL));
//		properties.put(PROPERTY_NAME_HIBERNATE_CACHE_USER_QUERY, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CACHE_USER_QUERY));
//		properties.put(PROPERTY_NAME_HIBERNATE_CACHE_REGION_FACTORY_CLASS, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CACHE_REGION_FACTORY_CLASS));
//		properties.put(PROPERTY_NAME_HIBERNTTE_PROVIDER_CACHE, env.getRequiredProperty(PROPERTY_NAME_HIBERNTTE_PROVIDER_CACHE));
//		properties.put("hibernate.cache.provider_configuration_file_resource_path", "ehcache_h.xml");
		return properties;	
	}
	
	@Bean
	public HibernateTransactionManager transactionManager() {
		HibernateTransactionManager transactionManager = new HibernateTransactionManager();
		transactionManager.setSessionFactory(sessionFactory().getObject());
		return transactionManager;
	}
	
	@Bean
	public MultipartResolver multipartResolver(){
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(-1);
        return multipartResolver;
	}
	
//	@Bean
//    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
//        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
//        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
//        return ehCacheManagerFactoryBean;
//    }
//	
//    @Bean
//    public CacheManager cacheManager() {
//        EhCacheCacheManager cacheManager = new EhCacheCacheManager();
//        cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
//        return cacheManager;
//    }
	
	@Bean
	public UrlBasedViewResolver setupViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();
		resolver.setPrefix("/WEB-INF/pages/");
		resolver.setSuffix(".jsp");
		resolver.setViewClass(JstlView.class);
		return resolver;
	}
	
//	@Bean
//	public Servlet getCpdMaliCourrierServlet(){
////		Dynamic api = servletContext.addServlet("CpdMaliCourrierServlet", CpdMaliCourrierServlet.class);
////		api.addMapping("/cpdmalicourrier/*");
////		api.setLoadOnStartup(1);
//		return new CpdMaliCourrierServlet(null);
//	}
}
